package com.example.kingdee.jstSync.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson2.JSONArray;
import com.example.kingdee.KingdeeCreate.dto.CreateInDto;
import com.example.kingdee.KingdeeCreate.impl.CreateSalBillImpl;
import com.example.kingdee.block.JuShuiTanBlock;
import com.example.kingdee.common.StringUtils;
import com.example.kingdee.dto.PurchaseSyncDto;
import com.example.kingdee.dto.SyncDto;
import com.example.kingdee.entity.JstSalOrder;
import com.example.kingdee.entity.JstSalOrderUpload;
import com.example.kingdee.entity.SyncLog;
import com.example.kingdee.exception.ProcedureException;
import com.example.kingdee.jstSync.JstSyncAbstract;
import com.example.kingdee.jstSync.entity.JstResult;
import com.example.kingdee.kingdeeBridge.common.RequestResult;
import com.example.kingdee.mapper.TBxStMapper;
import com.example.kingdee.sqlTool.SqlTool;
import com.example.kingdee.sqlTool.sqltoolEnum.FormIdEnum;
import com.example.kingdee.util.JuShuiTanUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * 聚水潭采购订单同步实现类
 */
@Service
public class JstSalOrderSyncImpl extends JstSyncAbstract {

    @Autowired
    private JuShuiTanBlock juShuiTanBlock;
    @Autowired
    private CreateSalBillImpl createSalBill;

    @Autowired
    private TBxStMapper tBxStMapper;

    @Override
    public int getOrderInfoPage(SyncDto syncDto, PurchaseSyncDto purchaseSyncDtoPage) {
        return JuShuiTanUtil.getSalOrderInfoPage(purchaseSyncDtoPage, FormIdEnum.orderQuery, juShuiTanBlock.getAccessToken());
    }

    @Override
    public JstResult selectJstResult(SyncDto syncDto,  PurchaseSyncDto purchaseSyncDto) {
        JstResult jstResult = new JstResult();
        //制定查询状态
        purchaseSyncDto.setJstFormId(FormIdEnum.orderQuery.name());
        purchaseSyncDto.setStatusList(syncDto.getStatus());
        String jstInfoStr = juShuiTanBlock.getJstSalInfo(purchaseSyncDto);
        //格式化单据
        List<JstSalOrder> jstPurchases = JSONArray.parseArray(jstInfoStr, JstSalOrder.class);
        jstResult.setJstSalOrderList(jstPurchases);
        return jstResult;
    }

    @Override
    public void kingdeeSync(SyncDto syncDto, JstResult jstResult) {
        List<JstSalOrder> jstSalOrderList = jstResult.getJstSalOrderList();
        for (JstSalOrder jstSalOrder : jstSalOrderList) {
            try {
                // 处理单个订单
                processSingleOrder(jstSalOrder);
            } catch (Exception e) {
                // 记录未知异常日志
                createErrorLog(jstSalOrder, "处理过程中发生未知异常: " + e.getMessage());
            }
        }
    }

    /**
     * 处理单个订单
     */
    private void processSingleOrder(JstSalOrder jstSalOrder) {
        // 初始化同步日志
        SyncLog syncLog = initSyncLog(jstSalOrder);

        // 验证店铺和销售模式
        if (!validateShopAndModel(jstSalOrder, syncLog)) {
            return;
        }

        // 处理订单状态过滤（规定同步开始时间）
        if (!processOrderStatus(jstSalOrder, syncLog)) {
            return;
        }

        // 检查是否已处理过
        if (isAlreadyProcessed(jstSalOrder)) {
            return;
        }

        // 验证销售组织（确认销售组织和承运商）
        String orgNumber = validateSalesOrganization(jstSalOrder, syncLog);
        if (orgNumber == null) {
            return;
        }

        // 构建订单明细并同步
        buildAndSyncOrder(jstSalOrder, syncLog, orgNumber);
    }

    /**
     * 初始化同步日志
     */
    private SyncLog initSyncLog(JstSalOrder jstSalOrder) {
        SyncLog syncLog = new SyncLog();
        syncLog.setSyncType("销售订单同步");
        syncLog.setSyncTime(SqlTool.getNowForString());
        syncLog.setSyncUser("接口自动同步");
        syncLog.setIsDispose("未处理");
        syncLog.setSrcBill("聚水潭订单");
        syncLog.setTarBill("云星空销售订单");
        syncLog.setJstBillno(String.valueOf(jstSalOrder.getOId()));
        syncLog.setObjectId(String.valueOf(jstSalOrder.getOId()));
        return syncLog;
    }

    /**
     * 验证店铺和销售模式
     */
    private boolean validateShopAndModel(JstSalOrder jstSalOrder, SyncLog syncLog) {
        String shopName = jstSalOrder.getShopName();
        Map<String, String> customerInfo = tBxStMapper.selectShopModel(shopName);

        if (customerInfo == null || StringUtils.isEmpty(customerInfo.get("salModel"))) {
            syncLog.setSyncResult("同步失败");
            syncLog.setSyncErrorMsg("《" + shopName + "》店铺不存在，或者云星空客户未维护销售模式，请先维护后再进行同步");
            tBxStMapper.insertSyncLog(syncLog);
            return false;
        }
        return true;
    }

    /**
     * 处理订单状态过滤
     */
    private boolean processOrderStatus(JstSalOrder jstSalOrder, SyncLog syncLog) {
        String status = jstSalOrder.getStatus();
        Map<String, String> customerInfo = tBxStMapper.selectShopModel(jstSalOrder.getShopName());
        String salModel = customerInfo.get("salModel");

        if ("Sent".equals(status)) {
            // 已发货订单处理
            if (jstSalOrder.getSendDate() == null) {
                syncLog.setSyncResult("同步失败");
                syncLog.setSyncErrorMsg("发货日期为空，无法导入");
                tBxStMapper.insertSyncLog(syncLog);
                return false;
            }

            // 日期检查
            Date poDate = DateUtil.parse(String.valueOf(jstSalOrder.getSendDate()));
            Date comparePoDate = DateUtil.parse("2025-09-23");
            if (!comparePoDate.before(poDate)) {
                return false;
            }

            // 线下订单不处理已发货状态
            if ("XXQD".equals(salModel)) {
                return false;
            }
        } else if ("Delivering".equals(status)) {
            // 只处理线下订单的发货中状态
            if (!"XXQD".equals(salModel)) {
                return false;
            }
        } else {
            // 其他状态不处理
            return false;
        }

        return true;
    }

    /**
     * 检查是否已处理过
     */
    private boolean isAlreadyProcessed(JstSalOrder jstSalOrder) {
        int havaErrorLog = tBxStMapper.isHavaErrorLog(jstSalOrder.getOId());
        int isSync = tBxStMapper.isSync(jstSalOrder.getOId());
        return havaErrorLog > 0 || isSync > 0;
    }

    /**
     * 验证销售组织
     */
    private String validateSalesOrganization(JstSalOrder jstSalOrder, SyncLog syncLog) {
        int wmsCoId = jstSalOrder.getWmsCoId();
        String orgName = tBxStMapper.selectJstStockName(wmsCoId).trim();


        if (StringUtils.isEmpty(orgName)) {
            syncLog.setSyncResult("同步失败");
            syncLog.setSyncErrorMsg("《" + wmsCoId + "》发货仓对应组织不存在");
            tBxStMapper.insertSyncLog(syncLog);
            return null;
        }

        // 确定组织编号
        String orgNumber;
        if (orgName.contains("神翼")) {
            orgNumber = "002";
        } else if (orgName.contains("萨蒲")) {
            orgNumber = "001";
        } else {
            syncLog.setSyncResult("同步失败");
            syncLog.setSyncErrorMsg("《" + orgName.trim() + "》仓库既不属于神翼，也不属于萨蒲，无法同步");
            tBxStMapper.insertSyncLog(syncLog);
            return null;
        }


        //查询承运商,
        String logisticsCompany = jstSalOrder.getLogisticsCompany();//快递公司
        String receiverName = jstSalOrder.getReceiverName() == null ? "" : jstSalOrder.getReceiverName();//收件人
        String supNumber = "";
        if (logisticsCompany.equals("京东快递") || receiverName.equals("京东自营")){
            supNumber = "YF0007";
        }else {
            supNumber = tBxStMapper.selectSupNumber(orgName, jstSalOrder.getLogisticsCompany());
        }
        jstSalOrder.setSupNumber(supNumber);
        return orgNumber;
    }

    /**
     * 构建订单明细并同步
     */
    private void buildAndSyncOrder(JstSalOrder jstSalOrder, SyncLog syncLog, String orgNumber) {
        Map<String, String> customerInfo = tBxStMapper.selectShopModel(jstSalOrder.getShopName());
        List<JstSalOrder.ItemsBean> items = jstSalOrder.getItems();
        List<Map<String, Object>> entryList = new ArrayList<>();
        StringBuilder ngItemName = new StringBuilder();
        //查询发货仓名称
        String orgName = tBxStMapper.selectJstStockName(jstSalOrder.getWmsCoId()).trim();
        //判断是否委托销售
        String commissionSale = "0";
        if (orgName.equals("慈溪市神翼电子商务有限公司") || orgName.equals("神翼线下专仓库")){
            commissionSale = "1";
        }
        // 构建订单明细
        for (JstSalOrder.ItemsBean item : items) {
            ngItemName.append(item.getName());
            String skuId = item.getSkuId();

            // 检查物料是否存在
            int isItem = tBxStMapper.isItem(skuId, orgNumber);
            if (isItem > 0) {
                String logisticsCompany = jstSalOrder.getLogisticsCompany();//快递公司
                String receiverName = jstSalOrder.getReceiverName() == null ? "" : jstSalOrder.getReceiverName();//收件人
                String stockNumber = "";//02.00.72
                if (logisticsCompany.equals("京东快递")){
                    //快递公司的仓库判断优先级高于发货仓
                    commissionSale = "0";
                    stockNumber = "02.00.17";
                }else if (receiverName.equals("京东自营")){
                    //快递公司的仓库判断优先级高于发货仓
                    commissionSale = "0";
                    stockNumber = "04.01.04";
                }else {
                    //查询仓库
                    stockNumber = tBxStMapper.getStockNumber(jstSalOrder.getWmsCoId());
                }

                Map<String, Object> entry = new HashMap<>();
                entry.put("itemNumber", skuId);
                entry.put("qty", item.getQty());
                entry.put("price", item.getPrice());
                entry.put("commissionSale", commissionSale);
                if (!StringUtils.isEmpty(stockNumber)){
                    entry.put("stockNumber", stockNumber);
                }
                //查询物料的制造策略
                String itemPlanMto = tBxStMapper.getItemPlanMto(skuId, orgNumber);
                if (itemPlanMto.equals("ZZCL003_SYS")){
                    //查询计划跟踪号
                    String planFlotNumber = getPlanFlotNumber(skuId, orgNumber, item.getQty());
                    if (!StringUtils.isEmpty(planFlotNumber)){
                        entry.put("planFlotNumber", planFlotNumber);
                    }
                }
                entryList.add(entry);
            } else {
                // 自动同步物料
                System.out.println("自动同步物料");
            }
        }

        // 同步订单
        if (entryList.isEmpty()) {
            syncLog.setSyncResult("同步失败");
            syncLog.setSyncErrorMsg("物料在云星空中不存在");
            syncLog.setObjectId(ngItemName.toString());
            tBxStMapper.insertSyncLog(syncLog);
            return;
        }

        // 创建并同步销售订单
        CreateInDto createInDto = buildCreateInDto(jstSalOrder, customerInfo, orgNumber, entryList);
        syncSalesOrder(jstSalOrder, syncLog, createInDto);
    }

    public String getPlanFlotNumber(String itemNumber, String orgNumber, double qty){
        String result = "";
        BigDecimal qtyBD = BigDecimal.valueOf(qty);
        // 查询当前物料未出库销售订单数量（返回BigDecimal类型）
        Map<String, BigDecimal> noOutStockQty = tBxStMapper.selectSalNoOutQty(itemNumber, orgNumber);
        if (noOutStockQty != null){
            // 查询物料的库存数量（返回BigDecimal类型）
            Map<String, BigDecimal> inventQty = tBxStMapper.selectItemInventQty(itemNumber, orgNumber);
            if (inventQty == null){
                return result;
            }
            // 获取BigDecimal值，如果为null则使用零值
            BigDecimal noOutTotal = noOutStockQty.getOrDefault("totalItemQty", BigDecimal.ZERO);
            BigDecimal inventTotal = inventQty.getOrDefault("totalItemQty", BigDecimal.ZERO);
            BigDecimal inventNotNull = inventQty.getOrDefault("notNullMtoNoQty", BigDecimal.ZERO);
            BigDecimal noOutNotNull = noOutStockQty.getOrDefault("notNullMtoNoQty", BigDecimal.ZERO);
            BigDecimal inventNull = inventQty.getOrDefault("nullMtoNoQty", BigDecimal.ZERO);
            BigDecimal noOutNull = noOutStockQty.getOrDefault("nullMtoNoQty", BigDecimal.ZERO);

            // 条件判断
            if (noOutTotal.compareTo(inventTotal) >= 0 ||
                    inventTotal.compareTo(BigDecimal.ZERO) <= 0 ||
                    inventNotNull.compareTo(BigDecimal.ZERO) <= 0) {
                // 未出库数量大于库存量 || 库存量小于等于0 || 有跟踪号的库存量小于等于0，直接返回空
                return null;
            }

            if (noOutNotNull.compareTo(inventNotNull) >= 0) {
                // 未出库数量中加了计划跟踪号的数量大于等于即时库存加了计划跟踪号数量，直接返回空
                return null;
            }

            BigDecimal nullMtoNoQtyCan = inventNull.subtract(noOutNull); // 不带跟踪号即时库存剩余数量
            if (nullMtoNoQtyCan.compareTo(qtyBD) >= 0) {
                // 如果当前不带跟踪号即时库存剩余数量大于等于历史销售订单不带跟踪号的数量，则直接返回空
                return null;
            } else {
                BigDecimal notNullMtoNoQtyCan = inventNotNull.subtract(noOutNotNull); // 带跟踪号即时库存剩余数量
                if (notNullMtoNoQtyCan.compareTo(qtyBD) >= 0) {
                    // 找到当前可出库的计划跟踪号
                    List<Map<String, Object>> mtoNoList = tBxStMapper.selectItemMtoNoList(itemNumber, orgNumber);
                    for (Map<String, Object> mtoNoMap : mtoNoList) {
                        // 当前跟踪号的库存数量
                        BigDecimal inventQtyMto = toBigDecimal(mtoNoMap.get("inventQty"));
                        String mtoNo = String.valueOf(mtoNoMap.get("mtoNo"));

                        // 查询当前计划跟踪号未出库的数量
                        BigDecimal noOutStockQtySum = tBxStMapper.getNoOutStockQty(itemNumber, orgNumber, mtoNo);

                        // 如果库存数量加当前销售订单数量大于未出库数量，则直接返回当前计划跟踪号
                        if (inventQtyMto.add(qtyBD).compareTo(noOutStockQtySum) > 0) {
                            return mtoNo;
                        }
                    }
                }
            }
        }else {
            // 查询物料的库存数量（返回BigDecimal类型）
            Map<String, BigDecimal> inventQty = tBxStMapper.selectItemInventQty(itemNumber, orgNumber);
            if (inventQty == null){
                return result;
            }
            BigDecimal inventTotal = inventQty.getOrDefault("totalItemQty", BigDecimal.ZERO);
            BigDecimal inventNotNull = inventQty.getOrDefault("notNullMtoNoQty", BigDecimal.ZERO);
            BigDecimal inventNull = inventQty.getOrDefault("nullMtoNoQty", BigDecimal.ZERO);
            if (inventNull.compareTo(BigDecimal.ZERO) > 0){
                return result;
            }
            if (inventNotNull.compareTo(BigDecimal.ZERO) > 0){
                // 找到当前可出库的计划跟踪号
                List<Map<String, Object>> mtoNoList = tBxStMapper.selectItemMtoNoList(itemNumber, orgNumber);
                for (Map<String, Object> mtoNoMap : mtoNoList) {
                    // 当前跟踪号的库存数量
                    BigDecimal inventQtyMto = toBigDecimal(mtoNoMap.get("inventQty"));
                    String mtoNo = String.valueOf(mtoNoMap.get("mtoNo"));
                    // 如果库存数量加当前销售订单数量大于未出库数量，则直接返回当前计划跟踪号
                    if (inventQtyMto.add(qtyBD).compareTo(qtyBD) > 0) {
                        return mtoNo;
                    }
                }
            }
        }

        return result;
    }

    // 辅助方法：确保其他查询结果也能转换为BigDecimal
    private BigDecimal toBigDecimal(Object value) {
        if (value == null) {
            return BigDecimal.ZERO;
        }
        if (value instanceof BigDecimal) {
            return (BigDecimal) value;
        }
        if (value instanceof Number) {
            return BigDecimal.valueOf(((Number) value).doubleValue());
        }
        return BigDecimal.ZERO;
    }

    //查询当前物料的计划跟踪号
//    public String getPlanFlotNumber(String itemNumber, String orgNumber, double qty){
//        String result = "";
//        //查询当前物料未出库销售订单数量
//        Map<String, Double> noOutStockQty = tBxStMapper.selectSalNoOutQty(itemNumber, orgNumber);
//        //查询物料的库存数量
//        Map<String, Double> inventQty = tBxStMapper.selectItemInventQty(itemNumber, orgNumber);
//        if (noOutStockQty.get("totalItemQty") >= inventQty.get("totalItemQty") || inventQty.get("totalItemQty") <= 0 || inventQty.get("notNullMtoNoQty") <= 0){
//            //未出库数量大于库存量 || 库存量小于等于0 || 有跟踪号的库存量小于等于0 ，直接返回空
//            return null;
//        }
//        if (noOutStockQty.get("notNullMtoNoQty") >= inventQty.get("notNullMtoNoQty")){
//            //未出库数量中加了计划跟踪号的数量大于等于即时库存加了计划跟踪号数量，直接返回空
//            return null;
//        }
//
//        double nullMtoNoQtyCan = NumberUtil.sub(inventQty.get("nullMtoNoQty"), noOutStockQty.get("nullMtoNoQty"));//不带跟踪号即使库存剩余数量
//        if (nullMtoNoQtyCan >= qty){
//            //如果当前剩余不带跟踪号的库存量大于等于历史销售订单不带跟踪号的数量，则直接返回空
//            return null;
//        }else {
//            double notNullMtoNoQtyCan = NumberUtil.sub(inventQty.get("notNullMtoNoQty"), noOutStockQty.get("notNullMtoNoQty"));//带跟踪号即时库存剩余数量
//            if (notNullMtoNoQtyCan >= qty){
//                //找到当前可出库的计划跟踪号
//                List<Map<String, Double>> mtoNoList = tBxStMapper.selectItemMtoNoList(itemNumber, orgNumber);
//                for (Map<String, Double> mtoNoMap : mtoNoList) {
//                    //当前跟踪号的库存数量
//                    double inventQtyMto = Double.parseDouble(String.valueOf(mtoNoMap.get("inventQty")));
//                    //查询当前计划跟踪号未出库的数量
//                    Double noOutStockQtySum = tBxStMapper.getNoOutStockQty(itemNumber, orgNumber, mtoNoMap.get("mtoNo"));
//                    //如果库存数量加当前销售订单数量大于未出库数量，则直接返回当前计划跟踪号
//                    if (NumberUtil.add(inventQtyMto, qty) > noOutStockQtySum){
//                        return String.valueOf(mtoNoMap.get("mtoNo"));
//                    }
//                }
//            }
//        }
//        return result;
//    }



    /**
     * 构建创建订单DTO
     */
    private CreateInDto buildCreateInDto(JstSalOrder jstSalOrder, Map<String, String> customerInfo, String orgNumber, List<Map<String, Object>> entryList) {
        int wmsCoId = jstSalOrder.getWmsCoId();
        String orgName = tBxStMapper.selectJstStockName(wmsCoId);
        CreateInDto createInDto = new CreateInDto();
        createInDto.setReserved1("XSDD01_SYS"); // 单据类型固定为标准销售订单
        createInDto.setReserved2(orgNumber); // 销售组织
        if (orgNumber.equals("001")){
            createInDto.setReserved3("100042_GW000004_100070"); // 萨蒲销售员固定为顾吉扬
        }else {
            createInDto.setReserved3("100012_GW000046_100070"); // 神翼销售员固定为张源源
        }
        createInDto.setReserved4(customerInfo.get("salModel")); // 销售模式
        createInDto.setReserved5(customerInfo.get("customerNumber")); // 客户编码
        createInDto.setReserved6(jstSalOrder.getLogisticsCompany()); // 快递公司
        createInDto.setReserved7(jstSalOrder.getLId()); // 快递单号
        createInDto.setReserved8(jstSalOrder.getOId()); // 聚水潭内部订单号
        createInDto.setReserved9(jstSalOrder.getOrderDate()); // 订单日期
        createInDto.setReserved10(jstSalOrder.getSendDate()); // 发货日期
        createInDto.setReserved11(customerInfo.get("salModel")); // 销售模式
        createInDto.setReserved12(jstSalOrder.getSupNumber()); // 承运商
        createInDto.setEntryList(entryList);

        return createInDto;
    }

    /**
     * 同步销售订单到金蝶
     */
    private void syncSalesOrder(JstSalOrder jstSalOrder, SyncLog syncLog, CreateInDto createInDto) {
        try {
            RequestResult kingdeeSal = createSalBill.createKingdeeSal(createInDto);
            if ("200".equals(kingdeeSal.getCode())) {
                syncLog.setSyncResult("同步成功");
                syncLog.setKingdeeBillno(kingdeeSal.getNumber());
                syncLog.setSyncErrorMsg("无");
            } else {
                syncLog.setSyncResult("同步失败");
                syncLog.setSyncErrorMsg(kingdeeSal.getMsg());
            }
        } catch (Exception e) {
            syncLog.setSyncResult("同步失败");
            syncLog.setSyncErrorMsg(e.getMessage());
        }

        tBxStMapper.insertSyncLog(syncLog);
    }

    /**
     * 创建错误日志
     */
    private void createErrorLog(JstSalOrder jstSalOrder, String errorMsg) {
        SyncLog syncLog = initSyncLog(jstSalOrder);
        syncLog.setSyncResult("同步失败");
        syncLog.setSyncErrorMsg(errorMsg);
        tBxStMapper.insertSyncLog(syncLog);
    }

    @Override
    protected void insertSyncLog(SyncDto syncDto, SyncLog syncLog, boolean isSucceed) {
        syncLog.setSyncType("采购订单同步");
        syncLog.setSrcBill("聚水潭采购单");
        syncLog.setTarBill("金蝶销售单");
        syncLog.setSyncTime(SqlTool.getNowForString());
        syncLog.setSyncUser(syncDto.getUserName() == null ? "系统自动同步" : syncDto.getUserName());
        if (isSucceed){
            syncLog.setSyncResult("同步成功");
            syncLog.setSyncErrorMsg("无");
        }else {
            syncLog.setIsDispose("未处理");
            syncLog.setSyncResult("同步失败");
        }
        tBxStMapper.insertSyncLog(syncLog);
    }
}
